package com.upcode.weighing.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.upcode.weighing.common.Constants;
import com.upcode.weighing.config.FileServerConfig;
import com.upcode.weighing.contant.FileContant;
import com.upcode.weighing.domain.SysFile;
import com.upcode.weighing.domain.SysFilePdfMidel;
import com.upcode.weighing.mapper.SysFileMapper;
import com.upcode.weighing.mapper.SysFilePdfMidelMapper;
import com.upcode.weighing.service.SysFileService;
import com.upcode.weighing.utils.Word2PdfUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDateTime;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 * 文件信息表 服务实现类
 * </p>
 *
 * @author ZYW
 * @since 2018-04-06
 */
@Slf4j
@Service
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {

    @Autowired
    private SysFilePdfMidelMapper sysFilePdfMidelMapper;

    @Autowired
    private FileServerConfig fileServerConfig;

    @Value("${file.address}")
    private String address;

    @Override
    public boolean save(SysFile sysFile) {
        sysFile.setId(IdWorker.getId());
        sysFile.setStatus(Constants.STATUS_NORMAL);
        return super.save(sysFile);
    }

    /**
     * 根据 源文件id 获取转换后的pdf文件
     * @param fileId
     * @return
     */
    @Override
    public SysFile findPdfFile(Long fileId) throws Exception {
        if(ObjectUtil.isNull(fileId)){
            throw new RuntimeException("文件编号不能为空");
        }
        SysFile sourceFile = super.getById(fileId);
        if(sourceFile.getStatus().intValue()!=Constants.STATUS_NORMAL){
            throw new RuntimeException("获取文件失败，或文件已删除");
        }
        if(StringUtils.equals(sourceFile.getExt(), FileContant.FILE_SUFFIX_PDF)){
            // 源文件是pdf不需要转换，直接返回
            return sourceFile;
        }
        if(!StringUtils.equals(sourceFile.getExt(), FileContant.FILE_SUFFIX_DOC) && !StringUtils.equals(sourceFile.getExt(),FileContant.FILE_SUFFIX_DOCX)){
            throw new RuntimeException("非word文件无需转换");
        }
        // 获取是否转换记录
        ReentrantLock lock = new ReentrantLock();
        try{
            lock.lock();
            // 获取已转换的记录
            QueryWrapper<SysFilePdfMidel> wrapper = new QueryWrapper<>();
            wrapper.eq("file_id",fileId);
            // 防止重复转化生成多个记录造成查询失败
            wrapper.last("limit 1");
            SysFilePdfMidel pdfMidel = sysFilePdfMidelMapper.selectOne(wrapper);
            if(ObjectUtil.isNull(pdfMidel)) {
                // 没有记录则转换文件
                return this.docConverter(sourceFile);
            }
            log.info("已有转换记录，无需转换");
            SysFile pdfFileMidel = new SysFile();
            BeanUtils.copyProperties(sourceFile,pdfFileMidel);
            pdfFileMidel.setName(pdfMidel.getName());
            pdfFileMidel.setPath(pdfFileMidel.getPath()) ;
            return pdfFileMidel;
        }catch (Exception e){
            log.info("转换文件失败 - 原因： {}",e.getMessage());
            throw new RuntimeException("转换文件失败");
        }finally {
            lock.unlock();
        }
    }

    // 转换文件并返回pdf文件信息
    @Override
    public SysFile docConverter(SysFile sourceFile) throws Exception {
        // 调用转换类
        String path = fileServerConfig.getPath();
        final String fileName = sourceFile.getName();
        final String filePath = sourceFile.getPath();
        String sourcePath = path + File.separator + filePath + File.separator + fileName;
        log.info("文件需要转换：源文件id: {} - sourcePath:{} - address{}",sourceFile.getId(),sourcePath,address);
        Word2PdfUtil docConverter = new Word2PdfUtil(address,sourcePath);
        docConverter.doc2pdf();
        String pdfName = fileName.substring(0,fileName.lastIndexOf("."));

        SysFilePdfMidel pdfMidel = new SysFilePdfMidel();
        pdfMidel.setFileId(sourceFile.getId());
        pdfMidel.setPath(sourceFile.getPath());
        pdfMidel.setName(pdfName+".pdf");
        pdfMidel.setCreateTime(LocalDateTime.now());
        sysFilePdfMidelMapper.insert(pdfMidel);

        SysFile pdfFileMidel  = new SysFile();
        pdfFileMidel.setId(sourceFile.getId());
        pdfFileMidel.setName(pdfMidel.getName());
        pdfFileMidel.setPath(pdfMidel.getPath());
        pdfFileMidel.setOrigName(sourceFile.getOrigName());
        return pdfFileMidel;
    }

}
